﻿using System;
using System.Collections.Generic;
using System.Web.UI;
using System.Web.UI.WebControls;
using Cms.Application.Admin.Presenters;
using Cms.Application.Admin.Views;
using Cms.Domain;
using Cms.Web.Framework.Controls;
using Cms.Web.UI.Admin.HelperClasses;
using iLib.Web.UI;
using DetailTemplate = Cms.Domain.DetailTemplate;
using MasterTemplate = Cms.Domain.MasterTemplate;

namespace Cms.Web.UI.Admin
{
    public partial class EditPage : AdminPage, IEditPageView
    {
        private EditPagePresenter _presenter;

        public override string HelpPage
        {
            get { return "dialogs/edit-page.aspx"; }
        }

        #region IEditPageView Members

        public int PageID
        {
            get
            {
                if (hidPageID.Value == string.Empty)
                {
                    hidPageID.Value = QueryString.GetInt32ID("id").ToString();
                }
                return int.Parse(hidPageID.Value);
            }
        }
        
        public void SetPageID(int id)
        {
            hidPageID.Value = id.ToString();
        }
        
        public string CurrentTab
        {
            get { return tabStrip.CurrentValue; }
        }
        
        public void SetFolders(string domain, IList<Folder> folders)
        {
            ddlFolders.Items.Add(new ListItem(domain, "-1"));
            SetFolderTree(1, folders);
        }
        
        public int SelectedFolderID
        {
            get { return int.Parse(ddlFolders.SelectedValue); }
            set { ddlFolders.SelectedValue = value.ToString(); }
        }

        public string Filename
        {
            get { return txtFilename.Text; }
            set { txtFilename.Text = value; }
        }
        
        public string Name
        {
            get { return txtName.Text; }
            set { txtName.Text = value; }
        }
        
        public string ContextTranslationFile
        {
            get { return "Admin/Translations/EditPage.xml"; }
        }
        
        public void SetMasterTemplates(IEnumerable<MasterTemplate> masterTemplates)
        {
            foreach (MasterTemplate mt in masterTemplates)
            {
                ddlMasterTemplates.Items.Add(new ListItem(mt.Name, mt.ID.ToString()));
            }
        }

        public void SetDetailTemplates(IEnumerable<DetailTemplate> detailTemplates)
        {
            foreach (DetailTemplate dt in detailTemplates)
            {
                ddlDetailTemplates.Items.Add(new ListItem(dt.Name, dt.ID.ToString()));
            }
        }
        
        public int SelectedMasterTemplateID
        {
            get { return int.Parse(ddlMasterTemplates.SelectedValue); }
            set { ddlMasterTemplates.SelectedValue = value.ToString(); }
        }
        
        public int SelectedDetailTemplateID
        {
            get { return int.Parse(ddlDetailTemplates.SelectedValue); }
            set { ddlDetailTemplates.SelectedValue = value.ToString(); }
        }

        private int CurrentLocaleID
        {
            get { return int.Parse(ViewState["CurrentLocaleID"].ToString()); }
            set { ViewState["CurrentLocaleID"] = value; }
        }

        public void SetLocales(IEnumerable<Locale> locales)
        {
            ddlPropertiesLocales.Items.Clear();
            ddlContentLocales.Items.Clear();
            foreach (Locale l in locales)
            {
                ddlPropertiesLocales.Items.Add(new ListItem(l.GetTranslation(Localization).Name, l.ID.ToString()));
                ddlContentLocales.Items.Add(new ListItem(l.GetTranslation(Localization).Name, l.ID.ToString()));
            }
        }
        
        public int SelectedLocaleID
        {
            get
            {
                return CurrentLocaleID;
            }
            set
            {
                ddlPropertiesLocales.SelectedValue = value.ToString();
                ddlContentLocales.SelectedValue = value.ToString();
                CurrentLocaleID = value;
            }
        }

        public void SetVersions(IList<ContentTranslationVersion> versions, int publishedVersionID)
        {
            ContentSetContainerHelper.SetVersions(
                versions,
                publishedVersionID,
                GetText(this, "NoContentVersions"),
                ref ddlVersions,
                ref lbPublish,
                ref hlPublishLater,
                ref lbSelectPublishedVersion,
                ref llNoVersionPublished);
        }
        
        public int SelectedVersionID
        {
            get { return int.Parse(ddlVersions.SelectedValue); }
            set { ddlVersions.SelectedValue = value.ToString(); }
        }
        
        public void SetScheduledPublishings(IList<ScheduledPublishing> scheduledPublishings)
        {
            rpScheduledPublishings.DataSource = scheduledPublishings;
            rpScheduledPublishings.DataBind();
            pnlScheduledPublishings.Visible = scheduledPublishings.Count > 0;
        }
        
        public string PageTitle
        {
            get { return txtTitle.Text; }
            set { txtTitle.Text = value; }
        }
        
        public string PageDescription
        {
            get { return txtDescription.Text; }
            set { txtDescription.Text = value; }
        }
        
        public string PageKeywords
        {
            get { return txtKeywords.Text; }
            set { txtKeywords.Text = value; }
        }
        
        public string ListingsTitle
        {
            get { return txtListingsTitle.Text; }
            set { txtListingsTitle.Text = value; }
        }
        
        public string ListingsDescription
        {
            get { return txtListingsDescription.Text; }
            set { txtListingsDescription.Text = value; }
        }
        
        public void SetCategories(
            IList<Category> rootCategories, 
            IList<Category> inheritedCategories,
            IList<Category> categories)
        {
            csCategories.SetCategories(rootCategories, inheritedCategories, categories);
            trCategories.Visible = rootCategories.Count > 0;
        }

        public IEnumerable<Category> GetSelectedCategories()
        {
            return csCategories.GetSelectedCategories();
        }
        
        public string SortKey
        {
            get { return txtSortKey.Text; }
            set { txtSortKey.Text = value; }
        }
        
        public void SetAllowedAdministratorGroups(
            IList<AdministratorGroup> availableGroups,
            IList<AdministratorGroup> inheritedGroups,
            IList<AdministratorGroup> groups)
        {
            gsAllowedAdministratorGroups.SetGroups(availableGroups, inheritedGroups, groups);
            trAllowedAdministratorGroups.Visible = availableGroups.Count > 0;
        }

        public IEnumerable<AdministratorGroup> GetSelectedAllowedAdministratorGroups()
        {
            return gsAllowedAdministratorGroups.GetSelectedGroups();
        }
        
        public void SetDeniedAdministratorGroups(
            IList<AdministratorGroup> availableGroups,
            IList<AdministratorGroup> inheritedGroups,
            IList<AdministratorGroup> groups)
        {
            gsDeniedAdministratorGroups.SetGroups(availableGroups, inheritedGroups, groups);
            trDeniedAdministratorGroups.Visible = availableGroups.Count > 0;
        }
        
        public IEnumerable<AdministratorGroup> GetSelectedDeniedAdministratorGroups()
        {
            return gsDeniedAdministratorGroups.GetSelectedGroups();
        }

        public void SetRequiredUserGroups(
            IList<UserGroup> availableGroups, 
            IList<UserGroup> inheritedGroups,
            IList<UserGroup> selectedGroups, 
            IList<UserGroup> deselectedGroups)
        {
            gsRequiredUserGroups.SetGroups(availableGroups, inheritedGroups, selectedGroups, deselectedGroups);
            trRequiredUserGroups.Visible = availableGroups.Count > 0;
        }
        
        public IEnumerable<UserGroup> GetSelectedRequiredUserGroups()
        {
            return gsRequiredUserGroups.GetSelectedGroups();
        }
        
        public IEnumerable<UserGroup> GetDeselectedUserGroups()
        {
            return gsRequiredUserGroups.GetDeselectedGroups();
        }
        
        public string HeadHtml
        {
            get { return txtHeadHtml.Text; }
            set { txtHeadHtml.Text = value; }
        }
        
        public string BodyTopHtml
        {
            get { return txtBodyTopHtml.Text; }
            set { txtBodyTopHtml.Text = value; }
        }
        
        public string BodyBottomHtml
        {
            get { return txtBodyBottomHtml.Text; }
            set { txtBodyBottomHtml.Text = value; }
        }
        
        public DateTime? StartPublishing
        {
            get
            {
                if (string.IsNullOrEmpty(txtStartPublishing.Text.Trim()))
                    return null;
                return DateTime.Parse(txtStartPublishing.Text);
            }
            set
            {
                txtStartPublishing.Text = value.HasValue
                                              ? value.Value.ToShortDateString() + " " + value.Value.ToShortTimeString()
                                              : string.Empty;
            }
        }

        public DateTime? EndPublishing
        {
            get
            {
                if (string.IsNullOrEmpty(txtEndPublishing.Text.Trim()))
                    return null;
                return DateTime.Parse(txtEndPublishing.Text);
            }
            set
            {
                txtEndPublishing.Text = value.HasValue
                                            ? value.Value.ToShortDateString() + " " + value.Value.ToShortTimeString()
                                            : string.Empty;
            }
        }
        
        public void PublishContentNotAllowed()
        {
            lbPublish.Visible = false;
        }
        
        public bool ShowCopyFromDefaultLocale
        {
            get { return lbCopyFromDefaultLocale.Visible; }
            set { lbCopyFromDefaultLocale.Visible = value; }
        }
        
        #endregion

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            _presenter = new EditPagePresenter(this);
            int selectedPropertiesLocaleIndex = ddlPropertiesLocales.SelectedIndex;
            int selectedContentLocaleIndex = ddlContentLocales.SelectedIndex;
            _presenter.UpdateLocales();
            ddlPropertiesLocales.SelectedIndex = selectedPropertiesLocaleIndex;
            ddlContentLocales.SelectedIndex = selectedContentLocaleIndex;
            if (!Page.IsPostBack)
            {
                if (PageID > 0)
                {
                    tabStrip.SelectedValue = Request.QueryString["tab"];
                }
                _presenter.Initialize();
                HeadingIcon = litIcon.Text;
            }
            _presenter.UpdateHeading();
            ddlPropertiesLocales.Attributes.Add(
                "onchange",
                "if (isDirty()) { " +
                "return cms.Dialogs.Confirm(" +
                "function (status) { " +
                "document.getElementById('ctl00_tabs_hidSave').value = status; " +
                "__doPostBack('ctl00$body$ddlPropertiesLocales',''); " +
                "}, " +
                "'" + GetText(this, "SaveInfoHeader") + "', " +
                "'" + GetText(this, "OptionalSaveInfoMessage") + "', " +
                "'" + GetText(this, "SaveInfoOK") + "', " +
                "'" + GetText(this, "SaveInfoCancel") + "', " +
                "true, " +
                "null" +
                "); } " +
                "else { " +
                "document.getElementById('ctl00_tabs_hidSave').value = 'cancel'; " +
                "cms.Edit.ShowTabOverlays(); " +
                "}");
            hlPublishLater.Attributes.Add(
                "onclick",
                "initInlineDateTimePicker(); cms.Dialogs.Confirm(schedulePublishingCallback, '" +
                GetText(this, "PublishLaterHeader") +
                "', null, '" +
                GetText(this, "SaveInfoOK") +
                "', '" +
                GetText(this, "SaveInfoCancel") +
                "', true, null, 'schedulePublishing');");

            // The scripts below is for the content editor: when clicking on a Master- or Detail Template, a warning message should be displayed.
            ClientScriptProxy.Current.RegisterClientScriptBlock(
                tabStrip, 
                GetType(), 
                "confirmTemplateContentEditing",
                "function confirmDetailTemplateContentEditing(redirectCallback) {" +
                "return cms.Dialogs.Confirm(redirectCallback, " +
                "'" +
                GetText(this, "EditDetailTemplateContentWarningHeader") +
                "', " +
                "'" +
                GetText(this, "EditDetailTemplateContentWarningMessage") +
                "', " +
                "'" +
                GetText(this, "EditDetailTemplateContentWarningOK") +
                "', " +
                "'" +
                GetText(this, "EditDetailTemplateContentWarningCancel") +
                "', " +
                "null, " +
                "null);" +
                "} " +
                "function confirmMasterTemplateContentEditing(redirectCallback) {" +
                "return cms.Dialogs.Confirm(redirectCallback, " +
                "'" +
                GetText(this, "EditMasterTemplateContentWarningHeader") +
                "', " +
                "'" +
                GetText(this, "EditMasterTemplateContentWarningMessage") +
                "', " +
                "'" +
                GetText(this, "EditMasterTemplateContentWarningOK") +
                "', " +
                "'" +
                GetText(this, "EditMasterTemplateContentWarningCancel") +
                "', " +
                "null, " +
                "null);" +
                "}",
                true);
        }
                
        protected void btnTriggerBreakContentLinkConfirmation_Click(object sender, EventArgs e)
        {
            string list = "<ul>";
            foreach (ContentSetContainer container in _presenter.GetContentContainers(hidBreakLinkAreaID.Value, hidBreakLinkContentType.Value))
            {
                list += "<li>" + Server.HtmlEncode(container.Name) + "</li>";
            }
            list += "</ul>";
            string script = "cms.Dialogs.Confirm(breakContentLinkCallback, " +
                            "'" + GetText(this, "BreakContentLinkHeader") + "', " +
                            "'" + GetText(this, "BreakContentLinkMessage").Replace("[List]", list).Replace("'", @"\'") +
                            "', " +
                            "'" + GetText(this, "BreakContentLinkOK") + "', " +
                            "'" + GetText(this, "BreakContentLinkCancel") + "', " +
                            "true, " +
                            "null);";
            ClientScriptProxy.Current.RegisterStartupScript(tabStrip, GetType(), "confirmBreakContentLink", script, true);
        }

        protected void btnBreakContentLink_Click(object sender, EventArgs e)
        {
            _presenter.BreakContentLink(hidBreakLinkAreaID.Value, hidBreakLinkContentType.Value);
            upnlContent.Update();
        }

        protected void btnSchedulePublishing_Click(object sender, EventArgs e)
        {
            _presenter.SchedulePublishing(int.Parse(ddlVersions.SelectedValue), DateTime.Parse(hidScheduledPublishing.Value));
            upnlContent.Update();
        }
        
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            tiBasicProperties.OnClientClick = GetClientClickScript(tiBasicProperties);
            tiLocalizedProperties.OnClientClick = GetClientClickScript(tiLocalizedProperties);
            tiContent.OnClientClick = GetClientClickScript(tiContent);
            if (tabStrip.CurrentValue != tabStrip.SelectedValue && hidSave.Value != "ok")
            {
                _presenter.RefreshProperties();
            }
            Page.Header.Controls.Add(new LiteralControl("<script type=\"text/javascript\">" +
                                                        DatePickerHelper.GetDatePickerSetup(Localization) +
                                                        Environment.NewLine +
                                                        DatePickerHelper.GetInlineDatePickerSetup(Localization, true) +
                                                        "</script>"));
        }
        
        protected override void OnPreRenderComplete(EventArgs e)
        {
            base.OnPreRenderComplete(e);
            if (tabStrip.SelectedValue == "basicproperties")
            {
                ifrBasicPropertiesPreview.Attributes.Add(
                    "src", 
                    "Admin/SitePreview.aspx?LocaleID=" + SelectedLocaleID +
                                            "&MasterTemplateID=" + SelectedMasterTemplateID +
                                            "&DetailTemplateID=" + SelectedDetailTemplateID);
                upnlBasicProperties.Update();
            }
            else if (tabStrip.SelectedValue == "content" && Request.Form[btnTriggerBreakContentLinkConfirmation.UniqueID] == null)
            {
                ifrContentPreview.Attributes.Add(
                    "src",
                    "Admin/SitePreview.aspx?PreviewMode=page&LocaleID=" + SelectedLocaleID +
                        "&MasterTemplateID=" + SelectedMasterTemplateID +
                        "&DetailTemplateID=" + SelectedDetailTemplateID +
                        "&PageID=" + PageID +
                        "&VersionID=" + SelectedVersionID +
                        "&AllowContentEditing=true");
                upnlContent.Update();
            }
            ClientScriptProxy.Current.RegisterStartupScript(
                tabStrip, 
                GetType(),
                "updatePanels",
                "updatePanels('" + tabStrip.SelectedValue + "');", 
                true);
            hlView.Visible = tabStrip.SelectedValue == "content";
            hlView.NavigateUrl = _presenter.GetPagePreviewUrl();
            lbSavePage.Visible = tabStrip.SelectedValue != "content";
            upnlButtons.Update();
        }

        protected void tabStrip_Click(string value)
        {
            Save();
            if (_presenter.IsValid)
            {
                ClientScriptProxy.Current.RegisterStartupScript(tabStrip, GetType(), "init", "init();", true);
            }
            upnlBasicProperties.Update();
            upnlLocalizedProperties.Update();
            upnlTabs.Update();
        }
        
        protected void lbSavePage_Click(object sender, EventArgs e)
        {
            Save();
            if (_presenter.IsValid)
            {
                Response.Redirect("Explorer.aspx");
            }
        }
        
        protected void ddlMasterTemplates_IndexChanged(object sender, EventArgs e)
        {
            upnlBasicProperties.Update();
        }
        
        protected void ddlDetailTemplates_IndexChanged(object sender, EventArgs e)
        {
            upnlBasicProperties.Update();
        }
        
        protected void ddlFolders_IndexChanged(object sender, EventArgs e)
        {
            _presenter.UpdateCategoriesAndGroups();
            upnlBasicProperties.Update();
        }
        
        protected void ddlLocales_IndexChanged(object sender, EventArgs e)
        {
            if (CurrentTab == "localizedproperties" && hidSave.Value == "ok")
            {
                _presenter.Save();
            }
            if (_presenter.IsValid)
            {
                ClientScriptProxy.Current.RegisterStartupScript(tabStrip, GetType(), "init", "init();", true);
            }
            CurrentLocaleID = int.Parse((sender as DropDownList).SelectedValue);
            ddlPropertiesLocales.SelectedValue = (sender as DropDownList).SelectedValue;
            ddlContentLocales.SelectedValue = (sender as DropDownList).SelectedValue;
            _presenter.SaveSelectedLocale();
            _presenter.RefreshProperties();
            _presenter.SetVersions();
            upnlLocalizedProperties.Update();
            upnlContent.Update();
            upnlTabs.Update();
        }
        
        protected void ddlVersions_IndexChanged(object sender, EventArgs e)
        {
            upnlContent.Update();
        }
        
        protected void lbPublish_Click(object sender, EventArgs e)
        {
            _presenter.Publish();
        }

        protected void lbSelectPublishedVersion_Click(object sender, EventArgs e)
        {
            ddlVersions.SelectedValue = (sender as LinkButton).CommandArgument;
            upnlContent.Update();
        }
        
        protected void rpScheduledPublishings_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem)
            {
                return;
            }
            var scheduledPublishing = (ScheduledPublishing)e.Item.DataItem;
            var litVersion = (Literal)e.Item.FindControl("litVersion");
            var litTimestamp = (Literal)e.Item.FindControl("litTimestamp");
            var lbDeleteScheduledPublishing = (LinkButton)e.Item.FindControl("lbDeleteScheduledPublishing");
            litVersion.Text = "#" + scheduledPublishing.ContentTranslationVersion.ID;
            var timestamp = new DateTime(long.Parse(scheduledPublishing.Timestamp));
            litTimestamp.Text = timestamp.ToShortDateString() + " " + timestamp.ToShortTimeString();
            lbDeleteScheduledPublishing.CommandArgument = scheduledPublishing.ID.ToString();
        }
        
        protected void lbCopyFromDefaultLocale_Click(object sender, EventArgs e)
        {
            upnlContent.Update();
        }
        
        protected void lbDeleteScheduledPublishing_Click(object sender, EventArgs e)
        {
            _presenter.DeleteScheduledPublishing(int.Parse((sender as LinkButton).CommandArgument));
            upnlContent.Update();
        }

        private void Save()
        {
            if (hidIsDirty.Value == "true" && (CurrentTab == "basicproperties" | CurrentTab == "localizedproperties") && hidSave.Value == "ok")
            {
                _presenter.Save();
            }
        }

        private string GetClientClickScript(AdminTabItem ti)
        {
            return "cms.Edit.ShowTabOverlays(); " +
                   "if (isDirty()) {" +
                   "return cms.Dialogs.Confirm(" +
                   "function (status) { " +
                   "document.getElementById('ctl00_tabs_hidSave').value = status;" +
                   "var pageID = document.getElementById('ctl00_tabs_hidPageID').value;" +
                   "if ((pageID == '' || pageID == '-1') && status != 'ok') " +
                   "cms.Edit.HideTabOverlays(); " +
                   "else " +
                   "__doPostBack('" + ti.UniqueID + "$" + ti.ID + "','');" +
                   "}, " +
                   "'" + GetText(this, "SaveInfoHeader") + "', " +
                   "'" + GetText(this, GetSaveInfoMessageKey()) + "', " +
                   "'" + GetText(this, "SaveInfoOK") + "', " +
                   "'" + GetText(this, "SaveInfoCancel") + "', " +
                   "true, " +
                   "null" +
                   ");" +
                   "}";
        }

        private string GetSaveInfoMessageKey()
        {
            return PageID > 0 ? "OptionalSaveInfoMessage" : "ForceSaveInfoMessage";
        }

        private void SetFolderTree(int level, IEnumerable<Folder> folders)
        {
            foreach (Folder f in folders)
            {
                string name = f.Name;
                for (int i = 0; i < level; i++)
                {
                    name = "&nbsp;&nbsp;&nbsp;&nbsp;" + name;
                }
                ddlFolders.Items.Add(new ListItem(name, f.ID.ToString()));
                SetFolderTree(level + 1, f.SubFolders);
            }
        }
    }
}